서버 컴포넌트에서 Blur이미지 처리하기
plaiceholder라이브러리와 삽질기
2024-02-01
서버 컴포넌트에서 Blur 이미지 처리하기
Next의 Image컴포넌트는 이미지가 로딩되기 전에 보여줄 placeholder속성을 기본적으로 제공해줍니다. 이 속성의 기본값은 empty지만 blur라는 속성을 갖을 수 있습니다.
이 속성은 layout shifts를 방지하기 위해 사용할 수 있습니다. 이미지를 불러오기 전까지 아무 화면에 반응이 없다가 이미지가 갑자기 나타나버리면 사용자 입장에서는 불편할 수 밖에 없습니다.
이 blur를 쓸 때는 blurDataURL이 필요합니다. 먼저 공식문서에서는 placeholder속성에 대해 다음과 같이 설명하고 있습니다.
'blur'를 선택하면, 'blurDataURL' 속성이 플레이스홀더로 사용됩니다. 만약 'src'가 정적으로 가져온 이미지(.jpg, .png, .webp, .avif)의 객체라면, 그 이미지가 애니메이션으로 감지되지 않는 한 'blurDataURL'이 자동으로 채워집니다.
동적 이미지의 경우, 'blurDataURL' 속성을 제공해야 합니다. 이러한 base64 생성에는 Plaiceholder와 같은 솔루션이 도움이 될 수 있습니다.
'data:image/...'를 선택하면, Data URL이 이미지가 로딩되는 동안 플레이스홀더로 사용됩니다.
'empty'를 선택하면, 이미지가 로딩되는 동안 플레이스홀더는 없으며 공간만 비워둡니다.
public폴더나 외부에서 이미지를 가져오는 경우 blurDataURL을 필수로 채워줘야 합니다. 이때 공식문서에서는 Plaiceholder 라이브러리를 추천하고 있습니다.
먼저 sharp와 plaiceholder, @plaiceholder/next 라이브러리가 필요합니다. plaiceholder는 ESM모듈로서만 제공하기 때문에 CommonJS의 require,module.exports를 사용할 수 없는데요, 따라서 next.config을 ESM모듈을 사용하도록 바꿀 필요가 있었습니다.(.mjs파일은 정석대로 ESM사양을 준수하는 자바스크립트 파일에 사용되는 확장자입니다.)
그 후 next config을 다음과 같이 수정하면 기본적인 사용준비를 마치게 됩니다!
이제 base64의 이미지를 만드는 유틸 함수를 만들어 보겠습니다. 이 함수는 plaiceholder의 getPlaiceholder를 사용하는데 다음과 같이 사용할 수 있습니다.
이 함수는 원본 이미지를 낮은 품질의 이미지 플레이스홀더(Low Quality Image Placeholder, LQIP)로 변환하는 역할을 합니다.
다만 plaiceholder가 브라우저에서 동작하지 않기 떄문에 서버 컴포넌트 내부에서만 사용해야 합니다.(클라이언트 컴포넌트에서는 사용할 수 없습니다.) 이제 base64의 이미지를 만드는 유틸을 작성해보겠습니다.
그리고 컴포넌트에서는 다음과 같이 가져와 사용합니다. async는 서버 컴포넌트에서만 동작하기 떄문에 위의 유틸을 클라이언트 컴포넌트에서 사용하는 것은 불가능합니다.
했던 고민
무조건 서버 컴포넌트에서만 사용한다는 제약이 존재해서, 결국 쓰고 있는 styled-components과 서버 컴포넌트에 대해 고민하게 된다. 서버컴포넌트를 잘 쓰기 위해서는 결국 tailwind나 CSS Module방식을 써야할 것 같은데 이미 많은 양의 코드를 styled-components로 적용해놓아서, 이를 바꾸는 것이 맞는지 고민이 된다...
vercel로 배포할 때 계속 빌드 에러가 떠서 많은 삽질을 했다.
찾아보니 sharp 0.33버전의 문제가 이슈로 등록되어 있었고 (관련 이슈), 버전을 0.31.3로 낮춰 해결했다.